home *** CD-ROM | disk | FTP | other *** search
- page 96,132
- ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
- ;§ §
- ;§ ディレクトリエントリ ソート ユーティリティ §
- ;§ §
- ;§ DSORT.EXE Ver1.30 §
- ;§ §
- ;§ Copyright (C) by 福地 邦雄 1991-1992. All rights reserved. §
- ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
- .MODEL SMALL,C
- ;
- REVERSE equ 1
- FALSE equ 0
- direntrysize equ 20h
- direntryseg equ 2
- ;
- public dirqsort,dirswap,sortfuncall
- ;
- .code
- ;
- ;------------------------------------------------------------------------------
- ;
- ; dirqsort
- ; ディレクトリエントリのクイックソート
- ;
- ; TYPE near call
- ; IN [SP+2] = ソートバッファセグメント
- ; [SP+4] = 要素数
- ; ES:[SP+6] = 比較関数リストアドレス
- ; OUT なし
- ; 保存レジスタ bp,ds
- ;
- ;------------------------------------------------------------------------------
- ;
- dirqsort proc sortobj,elmcount,funclist
- local cmpobj,chgedobj,cmpcount,chgcount,funcseg
- ;
- mov funcseg,es
- qsorthead:
- cmp elmcount,1
- ; @if (zf,off),and,(cf,off),L ; 要素数2以上ならソート実行
- jz @i0001
- jnc @i0002
- @i0001:
- jmp @i0003
- @i0002:
- mov dx,sortobj
- add dx,direntryseg
- cmp elmcount,02
- mov cmpobj,dx
- ; @if (zf,on) ; 要素数2なら直接比較
- jnz @i0004
- mov bx,funclist
- mov es,funcseg
- mov ds,sortobj
- call sortfuncall
- test ax,ax
- ; @if (zf,off),and,(sf,off) ; エントリ1が大きい時は入れ換え
- jz @i0005
- js @i0005
- mov es,cmpobj
- mov ds,sortobj
- call dirswap
- ; @ifend
- @i0005:
- ; @else ; 要素数3以上
- jmp @i0006
- @i0004:
- mov ax,elmcount ; 比較の基準を配列の真ん中から取り出す
- and ax,0fffeh
- add ax,sortobj
- mov es,ax
- mov ds,sortobj
- call dirswap
- mov ax,sortobj ; 準備
- mov chgcount,0
- mov cmpcount,1
- mov chgedobj,ax
- ; @do repeat
- @d0001:
- mov ax,cmpcount ; 比較終了か?
- ; @if (ax,>=,elmcount)
- cmp ax,elmcount
- jb @i0007
- ; @doexit
- jmp @d0002
- ; @ifend
- @i0007:
- mov dx,sortobj ; 比較関数呼び出し
- mov ds,cmpobj
- mov bx,funclist
- mov es,funcseg
- call sortfuncall
- test ax,ax
- ; @if (sf,on) ; 比較対象エントリが小さい時
- jns @i0008
- inc chgcount
- add chgedobj,direntryseg
- mov si,cmpobj
- mov es,si
- mov di,chgedobj
- mov ds,di
- ; @if (si,/=,di)
- cmp si,di
- je @i0009
- call dirswap
- ; @ifend
- @i0009:
- ; @ifend
- @i0008:
- add cmpobj,direntryseg ; 次の比較対象へ
- inc cmpcount
- ; @doend
- jmp @d0001
- @d0002:
- mov di,sortobj ;
- mov ds,di
- mov si,chgedobj
- mov es,si
- ; @if (si,/=,di)
- cmp si,di
- je @i0010
- call dirswap
- ; @ifend
- @i0010:
- mov bx,chgedobj ; 再帰呼び出し準備
- add bx,direntryseg
- mov cx,elmcount
- mov ax,chgcount
- sub cx,ax
- dec cx
- ; @if (cx,>,ax),S ; エントリ数の少ない方によって環境を整える
- cmp cx,ax
- jbe @i0011
- mov elmcount,cx ; 入れ換え済の方が少ない
- mov cx,ax
- xchg bx,sortobj
- ; @else
- jmp short @i0012
- @i0011:
- mov elmcount,ax ; 入れ換え無しの方が少ない
- ; @ifend
- @i0012:
- ; @if (cx,>,1) ; 要素数2以上なら
- cmp cx,1
- jbe @i0013
- mov es,funcseg ;
- push funclist ; 再帰呼び出し(エントリの少ない方)
- push cx
- push bx
- call dirqsort
- ; @ifend
- @i0013:
- jmp qsorthead ; 末尾再帰呼び出し(ループ)
- ; @ifend
- @i0006:
- ; @ifend
- @i0003:
- ret 6
- ;
- dirqsort endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; dirswap
- ; ディレクトリエントリの交換
- ;
- ; TYPE near call
- ; IN DS:0 = エントリ1アドレス
- ; ES:0 = エントリ2アドレス
- ; OUT なし
- ; 保存レジスタ bx,dx,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- dirswap proc
- ;
- mov cx,direntrysize/2
- xor si,si
- swaploop:
- mov ax,[si]
- xchg es:[si],ax
- mov [si],ax
- lea si,[si+2]
- loop swaploop
- ;
- ret
- ;
- dirswap endp
- ;
- ;------------------------------------------------------------------------------
- ;
- ; sortfuncall
- ; ソート用比較関数列の呼び出し
- ;
- ; TYPE near call
- ; IN ES:BX = 比較関数列のアドレス
- ; DS:0 = エントリ1アドレス
- ; DX:0 = エントリ2アドレス
- ; OUT AX = 比較結果
- ; 保存レジスタ si,di,bp,ds,es
- ;
- ;------------------------------------------------------------------------------
- ;
- sortfuncall proc
- ;
- ; @do until
- @d0003:
- call word ptr es:[bx] ; 比較関数呼び出し
- ; @if (word ptr es:[bx+2],=,REVERSE) ; 逆順指定の時は結果を反転
- cmp word ptr es:[bx+2],REVERSE
- jne @i0014
- neg ax
- ; @ifend
- @i0014:
- ; @if (ax,/=,0) ; 比較して違いがあれば終了
- or ax,ax
- je @i0015
- jmp compareend
- ; @ifend
- @i0015:
- lea bx,[bx+4] ; 次の比較関数へ
- ; @doend (word ptr es:[bx],=,0) ; 関数列の終了まで
- cmp word ptr es:[bx],0
- jne @d0003
- compareend:
- ret
- ;
- sortfuncall endp
- ;
- end